//
//  main.c
//  String
//
//  Created by admin on 2019/7/22.
//  Copyright © 2019 猫爷爷的酱醋茶. All rights reserved.
//

/*
 
 C语言中存储字符串
    1）原理：将字符串数据的每一个字符存储到字符数组中，并在后面追加一个"\0"代表字符串存储完毕
        “\0”为看不见的一个字符 ASCII码表中，为0。
 
    2）书写格式：
        a）char name[] = {"jack"};
           系统自动的会将这个字符串中的每一个字符存储到字符数组中，并自动追加"\0"结尾。
        b）最常用的方式：
            char name[] = “jack”; 长度为5；
            这个数组的长度为 字符串长度+1 因为最后还有个"\0"
            如果指定了字符串数组的长度，即为字符串数组指定的长度，char name[10] = "jack"; 长度为10；
 
        c）用字符指针来存储字符串的数据
            char* name = "jack"; 例：PointerStorageString();
 
            
 
 
    3）如果声明一个字符数组的同时，我们就初始化一个字符串给数组，这个时候可以有中文，即 char name[] = "猫爷爷的酱醋茶";
        一个中文占3个字节。
 
    4）使用格式控制%s，输出字符串 printf("%s",str);/puts();
        原理：从给定的地址开始，一个字节一个字节的输出，指导遇到‘\0’为止。
 
    5）使用scanf函数接收用户输入的字符串数据，并存储到指定的字符数组中
        a）scanf("%s",str); 这个时候不需要添加&取地址符，因为数组名就是代表地址
        b）需要注意的是，用户输入字符串的时候，如果输入了空格，系统就会认为输入结束。
           所以当输入有空格的时候可以使用gets();
 
    6）计算数组长度：不能使用sizeof()去计算，因为有可能字符串数组存储在数组中只占了小部分。
        a. 正确的计算方式，从第一个字节开始计数，直到遇到'\0'为止。
             int length = 0;
             while(str[length] ! = '\0')
             {
                length++;
             }
        b.使用strlen();函数，直接可以获取字符串数组中的字符数
            需要注意的是，该函数返回的是值需要用 unsigned long 类型的变量去接收，例：
            unsigned long length = strlen(str);
 
    7）strcmp()函数 比较
        cmp -> compare 比较两个字符数组的大小
        语法格式：
        strcmp(字符串1,字符串2);
        返回值是int类型。
 
        如果返回的是正数，就说明字符串1比字符串2大；
        如果返回的是负数，就说明字符串1比字符串2小；
        返回为0，则表示相等。
 
        比较规则：比的是相同位置的字符的ASCII码的大小。
 
    8）strcpy()函数 copy
        作用：把存储在一个字符数组的字符串数据拷贝到另一个字符数组中存储。
        语法格式：
        strcpy(str1,str2); str2字符串数组拷贝到str1字符串数组中。
 
    9）strcat()函数 拼接
        语法格式：
        strcat(str1,str2); 将str2的字符串接在str1的字符串后面，覆盖str1的'\0'；
 
 
 
 面试题:
 
    //字符数组内存空间不足导致的越界 例：MemoryOutOfBounds();
 
 
 
 
 */

#include <stdio.h>

//内存越界
void MemoryOutOfBounds(void);

//指针存储字符串
void PointerStorageString(void);

int main(int argc, const char * argv[])
{
    PointerStorageString();
    return 0;
}

//指针存储字符串
void PointerStorageString(void)
{
    
    //
    char* name = "猫爷爷的酱醋茶";
    printf("%s\n",name);
    
}

//内存越界
void MemoryOutOfBounds(void)
{
    char girlsName[] = "rose";
    char boysName[4] = "jack";
    printf("%s\n",boysName); //输出为 jackrose
    //数组向内存从高地址申请，girlsName[]存储在高字节，boysName[]存储在低字节，
    //因为boysName[4]的字符数不够，导致字符结尾'\0'不存在，导致内存穿透。
}
